#pragma once

#include <type_traits>

#include "base.h"

namespace mdtx::online::indicator
{
    /**
     * @brief Wrap a scale indicator to a band indicator
     *
     * @tparam ScImpl a scale indicator
     */
    template <typename ScImpl>
    class band_wrapper : public indi_base<typename ScImpl::scala_in,
                                          typename ScImpl::scala_out,
                                          ScImpl::num_in, 2>
    {
        using base = indi_base<typename ScImpl::scala_in,
                               typename ScImpl::scala_out,
                               ScImpl::num_in, 2>;
        using scale_indi_type = std::enable_if_t<ScImpl::num_out == 2, ScImpl>;

    public:
        using typename base::tuple_in;
        using typename base::tuple_out;
        using typename base::scala_in;
        using base::update;

    protected:
        scale_indi_type scale;
        scala_in z;

    public:
        template <typename... Args>
        explicit band_wrapper(scala_in z, Args... args)
            : scale(args...),
              z(z)
        {
        }

        tuple_out update(tuple_in const &in) override
        {
            auto [m, s] = scale.update(in);
            return tuple_out(m - z * s, m + z * s);
        }
    };
}
